package com.itheima.springbootwebtlias.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.springbootwebtlias.anno.LogOperation;
import com.itheima.springbootwebtlias.anno.MyLog;
import com.itheima.springbootwebtlias.exception.PasswordErrorException;
import com.itheima.springbootwebtlias.exception.UsernameNotExistException;
import com.itheima.springbootwebtlias.mapper.EmpExprMapper;
import com.itheima.springbootwebtlias.mapper.EmpMapper;
import com.itheima.springbootwebtlias.pojo.*;
import com.itheima.springbootwebtlias.service.EmpLogService;
import com.itheima.springbootwebtlias.service.EmpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.FileNotFoundException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class EmpServiceImpl implements EmpService {
    @Autowired
    private EmpMapper empMapper;//操作员工的持久层对象

    @Autowired
    private EmpExprMapper empExprMapper;//操作工作记录的持久层对象

    @Autowired
    private EmpLogService empLogService;//操作日志的业务层对象

    //分页和条件查询
    @Override
    public PageResult page(EmpQueryParam queryParam) {
        //1.使用分页插件来实现分页查询
        //1.1 启动分页插件                   页码                  条数
        PageHelper.startPage(queryParam.getPage(),queryParam.getPageSize());

        //1.2 调用被分页插件增强的持久层方法
        Page<Emp> page = empMapper.selectByCondition(queryParam);

        //1.3 从分页插件增强方法的返回结果中，获取数据封装到PageResult返回
        PageResult pageResult = new PageResult(page.getTotal(), page.getResult());
        return pageResult;
    }

    //添加员工
    //事务管理
    @LogOperation
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(Emp emp) throws FileNotFoundException {
        try {
            //调用持久层Mapper，向员工表中添加员工信息
            //补充基础数据
            emp.setCreateTime(LocalDateTime.now());
            emp.setUpdateTime(LocalDateTime.now());
            empMapper.insert(emp);//mybatis框架，设置主键返回

            //演示：编译时异常
//            if (true){
//                throw new FileNotFoundException();
//            }

            //2.如果有工作经历信息
            List<EmpExpr> exprList = emp.getExprList();
            if (exprList != null && exprList.size() > 0){
                //2.1 设置当前员工经历所属的员工信息0
                exprList.stream().forEach(ex -> ex.setEmpId(emp.getId()));
                //2.2 调用持久层Mapper，向工作经历表中添加工作经历信息
                //批量操作
                empExprMapper.insertBatch(exprList);
            }
        } finally {
            //3.记录操作日志
            EmpLog empLog = new EmpLog(emp.getId(),LocalDateTime.now(),"添加员工："+emp.getName());
            empLogService.insertLog(empLog);

        }
            /*
        spring框架提供：声明式事务，只需要添加注解即可进行事务控制管理
        //底层：动态代理
        //1.程序启动，spring框架扫描所有类中的所有方法
        //2.判断方法上是否添加了@Transactional注解
        //3.使用动态代理模式，创建当前类的代理对象，并将代理对象返回给spring容器管理，替换原来对象
           empServiceImplProxy.add(){

                try{
                    //开启事务
                    method.invoke(); //add()
                    //提交事务
                }catch(){
                    //回滚事务
                }
           }

     */

    }

    //批量删除员工
    @LogOperation
    @MyLog
    @Transactional
    @Override
    public void removeBatch(List<Integer> ids) {
        //1.调用持久层EmpMapper，批量删除员工信息
        empMapper.deleteBatchById(ids);

        //2.调用持久层EmpExprMapper，批量删除员工对应的工作经历信息
        empExprMapper.deleteBatchByEmpIds(ids);
    }

    //查询员工信息
    @Override
    public Emp  queryById(Integer id) {
        //1.调用持久层EmpMapper,根据id查询员工信息
        Emp emp = empMapper.selectById(id);//单表

        //2.调用持久层EmpExpreMapper,根据员工id查询员工对应的工作经历信息
        List<EmpExpr> exprList = empExprMapper.selectByEmpId(id);

        //3.封装到Emp返回
        emp.setExprList(exprList);

        return emp;
    }

    //更新员工信息
    @LogOperation
    @Transactional
    @Override
    public void update(Emp emp) {
        //调用持久层EmpMapper,更新员工信息
        emp.setUpdateTime(LocalDateTime.now());//同步更新时间
        empMapper.update(emp);

        //2.调用持久层EmpExpreMapper,更新员工对应的工作经历信息
        //2.1删除员工对应的工作信息
        List<Integer> ids = new ArrayList<>();
        ids.add(emp.getId());
        empExprMapper.deleteBatchByEmpIds(ids);

        //2.2批量添加员工对应的新的工作经历信息
        if (emp.getExprList()!=null && emp.getExprList().size()>0){
            //设置新增的所属员工信息
            emp.getExprList().stream().forEach(ex -> ex.setEmpId(emp.getId()));
            empExprMapper.insertBatch(emp.getExprList());
        }
    }

    //查询全部员工

    @Override
    public List<Emp> selectAllEmp() {
        List<Emp> empList = empMapper.selectAllEmp();
        return empList;
    }

    //登录校验
    @Override
    public Emp checkLogin(Emp emp) {
        //1.调用持久层EmpMapper,根据用户名和密码查询员工信息
        Emp resultEmp = empMapper.selectByUsername(emp.getUsername());

        //2.判断员工是否存在，如果不存在，账户不存在（登录失败）
        if (resultEmp == null){
            //业务异常，走异常处理机制，全局异常处理器，封装登录失败结果
            throw new UsernameNotExistException("账户不存在");
        }

        //3.如果存在，比较密码，如果不匹配，密码错误（登录失败）
        if (!Objects.equals(resultEmp.getPassword(),emp.getPassword())){
            //业务异常，走异常处理机制，全局异常处理器，封装登录失败结果
            throw new PasswordErrorException("密码错误");
        }

        //4.登录成功，返回员工信息
        return resultEmp;
    }


}
